package han.chensing.latos.game.elements.notes;

import com.badlogic.gdx.graphics.g2d.Batch;
import com.badlogic.gdx.graphics.g2d.TextureRegion;

import han.chensing.latos.game.elements.LatosElement;
import han.chensing.latos.game.processor.JudgeHandler;
import han.chensing.latos.game.util.MathUtil;

public abstract class Note extends LatosElement {

    public static final float scale=1.0f;

    protected float distanceHeight;
    protected int distanceToLineCenter;
    protected float hitTime;
    protected HitStatue hitStatue;
    protected NoteType noteType;
    protected boolean shown;
    protected boolean backGoing;
    protected Line bindLine;
    protected boolean scoreCounted;
    protected float trueX;
    protected float trueY;
    protected boolean up;

    public Note(Line line, TextureRegion textureRegion, NoteType type){
        super(textureRegion);
        this.shown=true;
        this.hitStatue=HitStatue.None;
        this.bindLine=line;
        this.noteType=type;
        this.backGoing =false;
        this.scoreCounted=false;
        setAlpha(1);
        setPosition(-getWidth()/2, -getHeight()/2);
        setCenter(0,0);
        setOrigin(0,0);
        setScale(scale);
        //setOrigin(100,100);
        //setCenter(100,100);
    }

    public enum HitStatue{
        None,Perfect,Good,Bad,Miss;
        float offset;
        public HitStatue setOffset(float offset){
            this.offset=offset;
            return this;
        }
        public float getOffset() {
            return offset;
        }
    }

    public enum NoteType{
        Tap,Drag,Flick,Hold,DirectFlick
    }

    @Override
    public void lAct(float delta, float currentTime) {
        super.lAct(delta, currentTime);
        float dt=currentTime-hitTime;
        if (hitStatue==HitStatue.None&&currentTime>=hitTime) {
            float alpha = Math.max(0, 1f - (dt/ JudgeHandler.BAD));
            setAlpha(alpha);
        }
        Line line=getBindLine();
        int degreeFix1=backGoing ? -1 : 1;
        int degreeFix2=backGoing ? 1 : 0;
        float distanceHeight = getDistanceHeight();
        float[] pos1= MathUtil.getPosOutOfLine(
                line.getX(),line.getY(),line.getRotation(),
                getDistanceToLineCenter()-getWidth()/2);
        float[] pos2= MathUtil.getPosOutOfLine(
                pos1[0],pos1[1], MathUtil.fixDegree(
                        line.getRotation()+90*degreeFix1),
                distanceHeight-getHeight()/2f*degreeFix1);
        float[] pos3 = MathUtil.getPosOutOfLine(pos1[0], pos1[1],
                MathUtil.fixDegree(line.getRotation()-180), -getWidth()/2);
        float[] pos4 = MathUtil.getPosOutOfLine(pos3[0], pos3[1],
                MathUtil.fixDegree(line.getRotation()+90*degreeFix1),
                distanceHeight);
        setPosition(pos2[0],pos2[1]);
        setRotation(getBindLine().getRotation());
        trueX=pos4[0];
        trueY=pos4[1];
    }

    @Override
    public void draw(Batch batch, float parentAlpha) {
        if (!isShown())
            return;
        //GameScreen.shapeRenderer.circle(getX(),getY(),3);
        //GameScreen.shapeRenderer.circle(getTrueX(),getTrueY(),3);
        super.draw(batch, parentAlpha);
        /*batch.setColor(1,1,1,parentAlpha);
        batch.draw(region,getX()-getWidth()/2f,getY()-getHeight()/2f,
                getOriginX(),getOriginY(),
                getWidth(),getHeight(),getScaleX(),getScaleY(),getRotation());
        batch.setColor(1,1,1,1);*/
    }

    public void finalInit(){}

    public float getDistanceHeight() {
        return distanceHeight;
    }

    public void setDistanceHeight(float distanceHeight) {
        this.distanceHeight = distanceHeight;
    }

    public int getDistanceToLineCenter() {
        return distanceToLineCenter;
    }

    public void setDistanceToLineCenter(int distanceToLineCenter) {
        this.distanceToLineCenter = distanceToLineCenter;
    }

    public float getHitTime() {
        return hitTime;
    }

    public void setHitTime(float hitTime) {
        this.hitTime = hitTime;
    }

    public HitStatue getHitStatue() {
        return hitStatue;
    }

    public void setHitStatue(HitStatue hitStatue) {
        this.hitStatue = hitStatue;
    }

    public boolean isShown() {
        return shown;
    }

    public void setShown(boolean shown) {
        this.shown = shown;
    }

    public Line getBindLine() {
        return bindLine==null?null:bindLine;
    }

    public void setBindLine(Line bindLine) {
        this.bindLine = bindLine;
    }

    public NoteType getNoteType() {
        return noteType;
    }

    public float getTrueX() {
        return trueX;
    }

    public void setTrueX(float trueX) {
        this.trueX = trueX;
    }

    public float getTrueY() {
        return trueY;
    }

    public void setTrueY(float trueY) {
        this.trueY = trueY;
    }

    public boolean isBackGoing() {
        return backGoing;
    }

    public void setBackGoing(boolean backGoing) {
        this.backGoing = backGoing;
    }

    public boolean isScoreCounted() {
        return scoreCounted;
    }

    public void setScoreCounted(boolean scoreCounted) {
        this.scoreCounted = scoreCounted;
    }

    public boolean isUp() {
        return up;
    }

    public void setUp(boolean up) {
        this.up = up;
    }
}
